home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / DirectPlay / Tutorials / Tut06_HostMigration / HostMigration.cpp next >
C/C++ Source or Header  |  2001-10-08  |  23KB  |  703 lines

  1. //----------------------------------------------------------------------------
  2. // File: HostMigration.cpp
  3. //
  4. // Desc: This simple program builds upon the last tutorial and adds host migration
  5. //
  6. // Copyright (c) 2000-2001 Microsoft Corp. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define INITGUID
  9. #define _WIN32_DCOM
  10. #include <stdio.h>
  11. #include <dplay8.h>
  12.  
  13.  
  14.  
  15. //-----------------------------------------------------------------------------
  16. // App specific structures 
  17. //-----------------------------------------------------------------------------
  18. struct HOST_NODE
  19. {
  20.     DPN_APPLICATION_DESC*   pAppDesc;
  21.     IDirectPlay8Address*    pHostAddress;
  22.     WCHAR*                  pwszSessionName;
  23.  
  24.     HOST_NODE*              pNext;
  25. };
  26.  
  27.  
  28. //-----------------------------------------------------------------------------
  29. // Global variables
  30. //-----------------------------------------------------------------------------
  31. IDirectPlay8Peer*                   g_pDP               = NULL;
  32. IDirectPlay8Address*                g_pDeviceAddress    = NULL;
  33. IDirectPlay8Address*                g_pHostAddress      = NULL;
  34. BOOL                                g_bHost;
  35. HOST_NODE*                          g_pHostList         = NULL;
  36. CRITICAL_SECTION                    g_csHostList;
  37. DPNID                               g_dpnidLocalPlayer  = 0;
  38.  
  39.  
  40. // This GUID allows DirectPlay to find other instances of the same game on
  41. // the network.  So it must be unique for every game, and the same for 
  42. // every instance of that game.  // {2C6FEE8B-3088-4b74-B38F-A16D02DAD246}
  43. GUID g_guidApp = { 0x2c6fee8b, 0x3088, 0x4b74, { 0xb3, 0x8f, 0xa1, 0x6d, 0x2, 0xda, 0xd2, 0x46 } };
  44.  
  45.  
  46. //-----------------------------------------------------------------------------
  47. // Function-prototypes
  48. //-----------------------------------------------------------------------------
  49. HRESULT WINAPI DirectPlayMessageHandler(PVOID pvUserContext, DWORD dwMessageId, PVOID pMsgBuffer);
  50. BOOL    IsServiceProviderValid(const GUID* pGuidSP);
  51. HRESULT InitDirectPlay();
  52. HRESULT CreateDeviceAddress();
  53. HRESULT CreateHostAddress(WCHAR* pwszHost);
  54. HRESULT HostSession();
  55. HRESULT EnumDirectPlayHosts();
  56. HRESULT ConnectToSession();
  57. HRESULT SendDirectPlayMessage();
  58. void    CleanupDirectPlay();
  59.  
  60.  
  61. //-----------------------------------------------------------------------------
  62. // Miscellaneous helper functions
  63. //-----------------------------------------------------------------------------
  64. #define SAFE_DELETE(p)          {if(p) {delete (p);     (p)=NULL;}}
  65. #define SAFE_DELETE_ARRAY(p)    {if(p) {delete[] (p);   (p)=NULL;}}
  66. #define SAFE_RELEASE(p)         {if(p) {(p)->Release(); (p)=NULL;}}
  67.  
  68. #define USER_HOST       1
  69. #define USER_CONNECT    2
  70. #define USER_EXIT       1
  71. #define USER_SEND       2
  72.  
  73.  
  74.  
  75.  
  76. //-----------------------------------------------------------------------------
  77. // Name: main()
  78. // Desc: Entry point for the application.  
  79. //-----------------------------------------------------------------------------
  80. int main(int argc, char* argv[], char* envp[])
  81. {
  82.     HRESULT                     hr;
  83.     int                         iUserChoice;
  84.  
  85.     // Init COM so we can use CoCreateInstance
  86.     CoInitializeEx(NULL, COINIT_MULTITHREADED);
  87.  
  88.     // Init the DirectPlay system
  89.     if( FAILED( hr = InitDirectPlay() ) )
  90.     {
  91.         printf("Failed Initializing DirectPlay:  0x%X\n", hr);
  92.         goto LCleanup;
  93.     }
  94.  
  95.     InitializeCriticalSection(&g_csHostList);
  96.  
  97.     // Get the necessary user input on whether they are hosting or connecting
  98.     do
  99.     {
  100.         printf("Please select one.\n1.  Host\n2.  Connect\n");
  101.         scanf("%d", &iUserChoice);
  102.     } while (iUserChoice != USER_HOST && iUserChoice != USER_CONNECT);
  103.  
  104.  
  105.     if( FAILED( hr = CreateDeviceAddress() ) )
  106.     {
  107.         printf("Failed CreatingDeviceAddress:  0x%X\n", hr);
  108.         goto LCleanup;
  109.     }
  110.  
  111.     if( iUserChoice == USER_HOST)
  112.     {
  113.         if( FAILED( hr = HostSession() ) )
  114.         {
  115.             printf("Failed Hosting:  0x%X\n", hr);
  116.             goto LCleanup;
  117.         }
  118.     }
  119.     else
  120.     {
  121.         if( FAILED( hr = EnumDirectPlayHosts() ) )
  122.         {
  123.             printf("Failed Enumerating Host:  0x%X\n", hr);
  124.             goto LCleanup;
  125.         }
  126.  
  127.         if( FAILED( hr = ConnectToSession() ) )
  128.         {
  129.             printf("Failed Connect to Host:  0x%X\n", hr);
  130.             goto LCleanup;
  131.         }
  132.         else
  133.         {
  134.             printf("\nConnection Successful.\n");
  135.         }
  136.     }
  137.  
  138.     // Present User with Choices
  139.     do
  140.     {
  141.         printf("Please select one.\n1.  Exit\n2.  Send Data\n");
  142.         scanf("%d", &iUserChoice);
  143.  
  144.         if( iUserChoice == USER_SEND)
  145.         {
  146.             if( FAILED( hr = SendDirectPlayMessage() ) )
  147.             {
  148.                 printf("Failed To Send Data:  0x%X\n", hr);
  149.                 goto LCleanup;
  150.             }
  151.         }
  152.     } while (iUserChoice != USER_EXIT);
  153.  
  154. LCleanup:
  155.     CleanupDirectPlay();
  156.  
  157.     // Cleanup COM
  158.     CoUninitialize();
  159.  
  160.     return 0;
  161. }
  162.  
  163.  
  164.  
  165.  
  166. //-----------------------------------------------------------------------------
  167. // Name: InitDirectPlay()
  168. // Desc: Initialize DirectPlay
  169. //-----------------------------------------------------------------------------
  170. HRESULT InitDirectPlay()
  171. {
  172.     HRESULT     hr = S_OK;
  173.  
  174.     // Create the IDirectPlay8Peer Object
  175.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay8Peer, NULL, 
  176.                                        CLSCTX_INPROC_SERVER,
  177.                                        IID_IDirectPlay8Peer, 
  178.                                        (LPVOID*) &g_pDP ) ) )
  179.     {
  180.         printf("Failed Creating the IDirectPlay8Peer Object:  0x%X\n", hr);
  181.         goto LCleanup;
  182.     }
  183.  
  184.     // Init DirectPlay
  185.     if( FAILED( hr = g_pDP->Initialize(NULL, DirectPlayMessageHandler, 0 ) ) )
  186.     {
  187.         printf("Failed Initializing DirectPlay:  0x%X\n", hr);
  188.         goto LCleanup;
  189.     }
  190.     
  191.     // Ensure that TCP/IP is a valid Service Provider
  192.     if( FALSE == IsServiceProviderValid(&CLSID_DP8SP_TCPIP ) )
  193.     {
  194.         hr = E_FAIL;
  195.         printf("Failed validating CLSID_DP8SP_TCPIP");
  196.         goto LCleanup;
  197.     }
  198.  
  199. LCleanup:
  200.     return hr;
  201. }
  202.  
  203.  
  204.  
  205.  
  206. //-----------------------------------------------------------------------------
  207. // Name: IsServiceProviderValid()
  208. // Desc: Return TRUE if the service provider is valid
  209. //-----------------------------------------------------------------------------
  210. BOOL IsServiceProviderValid(const GUID* pGuidSP)
  211. {
  212.     HRESULT                     hr;
  213.     DPN_SERVICE_PROVIDER_INFO*  pdnSPInfo = NULL;
  214.     DWORD                       dwItems = 0;
  215.     DWORD                       dwSize = 0;
  216.  
  217.     hr = g_pDP->EnumServiceProviders( &CLSID_DP8SP_TCPIP, NULL, NULL, &dwSize, &dwItems, 0);
  218.  
  219.     if( hr != DPNERR_BUFFERTOOSMALL)
  220.     {
  221.         printf("Failed Enumerating Service Providers:  0x%x\n", hr);
  222.         goto LCleanup;
  223.     }
  224.  
  225.     pdnSPInfo = (DPN_SERVICE_PROVIDER_INFO*) new BYTE[dwSize];
  226.  
  227.     if( FAILED( hr = g_pDP->EnumServiceProviders( &CLSID_DP8SP_TCPIP, NULL, pdnSPInfo, &dwSize, &dwItems, 0 ) ) )
  228.     {
  229.         printf("Failed Enumerating Service Providers:  0x%x\n", hr);
  230.         goto LCleanup;
  231.     }
  232.  
  233.     // There are no items returned so the requested SP is not available
  234.     if( dwItems == 0)
  235.     {
  236.         hr = E_FAIL;
  237.     }
  238.  
  239. LCleanup:
  240.     SAFE_DELETE_ARRAY(pdnSPInfo);
  241.     if( SUCCEEDED(hr) )
  242.         return TRUE;
  243.     else
  244.         return FALSE;
  245. }
  246.  
  247.  
  248.  
  249.  
  250. //-----------------------------------------------------------------------------
  251. // Name: DirectPlayMessageHandler
  252. // Desc: Handler for DirectPlay messages.  
  253. //-----------------------------------------------------------------------------
  254. HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext, DWORD dwMessageId, 
  255.                                          PVOID pMsgBuffer )
  256. {
  257.     HRESULT     hr = S_OK;
  258.  
  259.     switch (dwMessageId)
  260.     {
  261.         case DPN_MSGID_ENUM_HOSTS_RESPONSE:
  262.         {
  263.             PDPNMSG_ENUM_HOSTS_RESPONSE pEnumHostsResponseMsg;
  264.             const DPN_APPLICATION_DESC* pAppDesc;
  265.             HOST_NODE*                  pHostNode   = NULL;
  266.             WCHAR*                      pwszSession = NULL;
  267.  
  268.             pEnumHostsResponseMsg = (PDPNMSG_ENUM_HOSTS_RESPONSE) pMsgBuffer;
  269.             pAppDesc = pEnumHostsResponseMsg->pApplicationDescription;
  270.  
  271.             // Insert each host response if it isn't already present
  272.             EnterCriticalSection(&g_csHostList);
  273.  
  274.             for (pHostNode = g_pHostList; pHostNode; pHostNode = pHostNode->pNext)
  275.             {
  276.                 if( pAppDesc->guidInstance == pHostNode->pAppDesc->guidInstance)
  277.                 {
  278.                     // This host is already in the list
  279.                     pHostNode = NULL;
  280.                     goto Break_ENUM_HOSTS_RESPONSE;
  281.                 }
  282.             }
  283.  
  284.             // This host session is not in the list then so insert it.
  285.             pHostNode = new HOST_NODE;
  286.             if( pHostNode == NULL)
  287.             {
  288.                 goto Break_ENUM_HOSTS_RESPONSE;
  289.             }
  290.  
  291.             ZeroMemory(pHostNode, sizeof(HOST_NODE));
  292.  
  293.             // Copy the Host Address
  294.             if( FAILED( pEnumHostsResponseMsg->pAddressSender->Duplicate(&pHostNode->pHostAddress ) ) )
  295.             {
  296.                 goto Break_ENUM_HOSTS_RESPONSE;
  297.             }
  298.  
  299.             pHostNode->pAppDesc = new DPN_APPLICATION_DESC;
  300.  
  301.             if( pHostNode == NULL)
  302.             {
  303.                 goto Break_ENUM_HOSTS_RESPONSE;
  304.             }
  305.  
  306.             ZeroMemory(pHostNode->pAppDesc, sizeof(DPN_APPLICATION_DESC));
  307.             memcpy(pHostNode->pAppDesc, pAppDesc, sizeof(DPN_APPLICATION_DESC));
  308.  
  309.             // Null out all the pointers we aren't copying
  310.             pHostNode->pAppDesc->pwszSessionName = NULL;
  311.             pHostNode->pAppDesc->pwszPassword = NULL;
  312.             pHostNode->pAppDesc->pvReservedData = NULL;
  313.             pHostNode->pAppDesc->dwReservedDataSize = 0;
  314.             pHostNode->pAppDesc->pvApplicationReservedData = NULL;
  315.             pHostNode->pAppDesc->dwApplicationReservedDataSize = 0;
  316.             
  317.             if( pAppDesc->pwszSessionName)
  318.             {
  319.                 pwszSession = new WCHAR[wcslen(pAppDesc->pwszSessionName) + 1];
  320.                 
  321.                 if( pwszSession)
  322.                 {
  323.                     wcscpy(pwszSession, pAppDesc->pwszSessionName);
  324.                 }
  325.             }
  326.  
  327.             pHostNode->pwszSessionName = pwszSession;
  328.  
  329.             // Insert it onto the front of the list
  330.             pHostNode->pNext = g_pHostList ? g_pHostList->pNext : NULL;
  331.             g_pHostList = pHostNode;
  332.             pHostNode = NULL;
  333.  
  334. Break_ENUM_HOSTS_RESPONSE:
  335.             LeaveCriticalSection(&g_csHostList);
  336.  
  337.             if( pHostNode)
  338.             {
  339.                 SAFE_RELEASE(pHostNode->pHostAddress);
  340.  
  341.                 SAFE_DELETE(pHostNode->pAppDesc);
  342.  
  343.                 delete pHostNode;
  344.             }
  345.  
  346.             break;
  347.         }
  348.     
  349.         case DPN_MSGID_RECEIVE:
  350.         {
  351.             PDPNMSG_RECEIVE     pMsg;
  352.  
  353.             pMsg = (PDPNMSG_RECEIVE) pMsgBuffer;
  354.  
  355.             printf("\nReceived Message:  %S\n", (WCHAR*)pMsg->pReceiveData);
  356.             break;
  357.         }
  358.     
  359.         case DPN_MSGID_HOST_MIGRATE:
  360.         {
  361.             PDPNMSG_HOST_MIGRATE    pHostMigrateMsg;
  362.  
  363.             pHostMigrateMsg = (PDPNMSG_HOST_MIGRATE) pMsgBuffer;
  364.  
  365.             printf("\nHost Migration Has Occured.\n");
  366.  
  367.             // See if we are the new host
  368.             if( pHostMigrateMsg->dpnidNewHost == g_dpnidLocalPlayer)
  369.                 printf("You are the New Host\n");
  370.             else
  371.                 printf("DPNID of New Host is %d\n", pHostMigrateMsg->dpnidNewHost);
  372.  
  373.             break;
  374.         }
  375.     
  376.         case DPN_MSGID_CREATE_PLAYER:
  377.         {
  378.             PDPNMSG_CREATE_PLAYER   pCreatePlayerMsg;
  379.             DWORD                   dwSize = 0;
  380.             DPN_PLAYER_INFO*        pdpPlayerInfo = NULL;
  381.  
  382.             pCreatePlayerMsg = (PDPNMSG_CREATE_PLAYER)pMsgBuffer;
  383.  
  384.             // check to see if we are the player being created
  385.             hr = g_pDP->GetPeerInfo(pCreatePlayerMsg->dpnidPlayer, pdpPlayerInfo, &dwSize, 0);
  386.  
  387.             if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  388.             {
  389.                 printf("Failed GetPeerInfo:  0x%X\n", hr);
  390.                 return hr;
  391.             }
  392.  
  393.             pdpPlayerInfo = (DPN_PLAYER_INFO*) new BYTE[dwSize];
  394.             ZeroMemory(pdpPlayerInfo, dwSize);
  395.             pdpPlayerInfo->dwSize = sizeof(DPN_PLAYER_INFO);
  396.  
  397.             if( FAILED( hr = g_pDP->GetPeerInfo(pCreatePlayerMsg->dpnidPlayer, pdpPlayerInfo, &dwSize, 0 ) ) )
  398.             {
  399.                 printf("Failed GetPeerInfo:  0x%X\n", hr);
  400.                 goto Error_DPN_MSGID_CREATE_PLAYER;
  401.             }
  402.  
  403.             if( pdpPlayerInfo->dwPlayerFlags & DPNPLAYER_LOCAL)
  404.                 g_dpnidLocalPlayer = pCreatePlayerMsg->dpnidPlayer;
  405.  
  406. Error_DPN_MSGID_CREATE_PLAYER:
  407.             SAFE_DELETE_ARRAY(pdpPlayerInfo);
  408.             break;
  409.         }
  410.     }
  411.     return hr;
  412. }
  413.  
  414.  
  415.  
  416.  
  417. //-----------------------------------------------------------------------------
  418. // Name: EnumDirectPlayHosts()
  419. // Desc: Enumerates the hosts
  420. //-----------------------------------------------------------------------------
  421. HRESULT EnumDirectPlayHosts()
  422. {
  423.     HRESULT                 hr = S_OK;
  424.     WCHAR                   wszHost[128];
  425.     DPN_APPLICATION_DESC    dpAppDesc;
  426.     WCHAR*                  pwszURL = NULL;
  427.  
  428.     // Prompt for the hostname/ip
  429.     printf("\nPlease enter the IP address of host:\n");
  430.     wscanf(L"%ls", wszHost);
  431.  
  432.     if( FAILED( hr = CreateHostAddress(wszHost ) ) )
  433.     {
  434.         printf("Failed Creating Host Address:  0x%X\n", hr);
  435.         goto LCleanup;
  436.     }
  437.  
  438.     // Now set up the Application Description
  439.     ZeroMemory(&dpAppDesc, sizeof(DPN_APPLICATION_DESC));
  440.     dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
  441.     dpAppDesc.guidApplication = g_guidApp;
  442.  
  443.     // We now have the host address so lets enum
  444.     if( FAILED( hr = g_pDP->EnumHosts(&dpAppDesc,            // pApplicationDesc
  445.                                         g_pHostAddress,     // pdpaddrHost
  446.                                         g_pDeviceAddress,   // pdpaddrDeviceInfo
  447.                                         NULL, 0,            // pvUserEnumData, size
  448.                                         4,                  // dwEnumCount
  449.                                         0,                  // dwRetryInterval
  450.                                         0,                  // dwTimeOut
  451.                                         NULL,               // pvUserContext
  452.                                         NULL,               // pAsyncHandle
  453.                                         DPNENUMHOSTS_SYNC ) ) )// dwFlags
  454.     {
  455.         printf("Failed Enumerating the Hosts:  0x%X\n", hr);
  456.         goto LCleanup;
  457.     }
  458.  
  459. LCleanup:
  460.     return hr;
  461. }
  462.  
  463.  
  464.  
  465.  
  466. //-----------------------------------------------------------------------------
  467. // Name: CreateDeviceAddress()
  468. // Desc: Creates a device address
  469. //-----------------------------------------------------------------------------
  470. HRESULT CreateDeviceAddress()
  471. {
  472.     HRESULT         hr = S_OK;
  473.  
  474.     // Create our IDirectPlay8Address Device Address
  475.     if( FAILED( hr = CoCreateInstance(CLSID_DirectPlay8Address, NULL,
  476.                                     CLSCTX_INPROC_SERVER,
  477.                                     IID_IDirectPlay8Address,
  478.                                     (LPVOID*) &g_pDeviceAddress ) ) )
  479.     {
  480.         printf("Failed Creating the IDirectPlay8Address Object:  0x%X\n", hr);
  481.         goto LCleanup;
  482.     }
  483.     
  484.     // Set the SP for our Device Address
  485.     if( FAILED( hr = g_pDeviceAddress->SetSP(&CLSID_DP8SP_TCPIP ) ) )
  486.     {
  487.         printf("Failed Setting the Service Provider:  0x%X\n", hr);
  488.         goto LCleanup;
  489.     }
  490.  
  491. LCleanup:
  492.     return hr;
  493. }
  494.  
  495.  
  496.  
  497.  
  498. //-----------------------------------------------------------------------------
  499. // Name: CreateHostAddress()
  500. // Desc: Creates a host address
  501. //-----------------------------------------------------------------------------
  502. HRESULT CreateHostAddress(WCHAR* pwszHost)
  503. {
  504.     HRESULT         hr = S_OK;
  505.  
  506.     // Create our IDirectPlay8Address Host Address
  507.     if( FAILED( hr = CoCreateInstance(CLSID_DirectPlay8Address, NULL,
  508.                                     CLSCTX_INPROC_SERVER,
  509.                                     IID_IDirectPlay8Address,
  510.                                     (LPVOID*) &g_pHostAddress ) ) )
  511.     {
  512.         printf("Failed Creating the IDirectPlay8Address Object:  0x%X\n", hr);
  513.         goto LCleanup;
  514.     }
  515.     
  516.     // Set the SP for our Host Address
  517.     if( FAILED( hr = g_pHostAddress->SetSP(&CLSID_DP8SP_TCPIP ) ) )
  518.     {
  519.         printf("Failed Setting the Service Provider:  0x%X\n", hr);
  520.         goto LCleanup;
  521.     }
  522.  
  523.     // Set the hostname into the address
  524.     if( FAILED( hr = g_pHostAddress->AddComponent(DPNA_KEY_HOSTNAME, pwszHost,
  525.                                                     2*(wcslen(pwszHost) + 1), /*bytes*/
  526.                                                     DPNA_DATATYPE_STRING ) ) )
  527.     {
  528.         printf("Failed Adding Hostname to Host Address:  0x%X\n", hr);
  529.         goto LCleanup;
  530.     }
  531.  
  532. LCleanup:
  533.     return hr;
  534. }
  535.  
  536.  
  537.  
  538.  
  539. //-----------------------------------------------------------------------------
  540. // Name: HostSession()
  541. // Desc: Host a DirectPlay session
  542. //-----------------------------------------------------------------------------
  543. HRESULT HostSession()
  544. {
  545.     HRESULT                 hr = S_OK;
  546.     DPN_APPLICATION_DESC    dpAppDesc;
  547.     WCHAR                   wszSession[128];
  548.  
  549.  
  550.     // Prompt the user for the session name
  551.     printf("\nPlease Enter a Session Name.\n");
  552.     wscanf(L"%ls", wszSession);
  553.  
  554.     // Now set up the Application Description
  555.     ZeroMemory(&dpAppDesc, sizeof(DPN_APPLICATION_DESC));
  556.     dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
  557.     dpAppDesc.guidApplication = g_guidApp;
  558.     dpAppDesc.pwszSessionName = wszSession;
  559.     dpAppDesc.dwFlags = DPNSESSION_MIGRATE_HOST;
  560.  
  561.     // We are now ready to host the app
  562.     if( FAILED( hr = g_pDP->Host( &dpAppDesc,             // AppDesc
  563.                                   &g_pDeviceAddress, 1,   // Device Address
  564.                                   NULL, NULL,             // Reserved
  565.                                   NULL,                   // Player Context
  566.                                   0 ) ) )                    // dwFlags
  567.     {
  568.         printf("Failed Hosting:  0x%X\n", hr);
  569.         goto LCleanup;
  570.     }
  571.     else
  572.     {
  573.         printf("Currently Hosting...\n");
  574.     }
  575.  
  576.  
  577. LCleanup:
  578.     return hr;
  579. }
  580.  
  581.  
  582.  
  583.  
  584. //-----------------------------------------------------------------------------
  585. // Name: ConnectToSession()
  586. // Desc: Connects to a DirectPlay session
  587. //-----------------------------------------------------------------------------
  588. HRESULT ConnectToSession()
  589. {
  590.     HRESULT                     hr = E_FAIL;
  591.     DPN_APPLICATION_DESC        dpnAppDesc;
  592.     IDirectPlay8Address*        pHostAddress = NULL;
  593.  
  594.  
  595.     ZeroMemory(&dpnAppDesc, sizeof(DPN_APPLICATION_DESC));
  596.     dpnAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
  597.     dpnAppDesc.guidApplication = g_guidApp;
  598.  
  599.     // Simply connect to the first one in the list
  600.     EnterCriticalSection(&g_csHostList);
  601.  
  602.     if( g_pHostList && SUCCEEDED(hr = g_pHostList->pHostAddress->Duplicate(&pHostAddress ) ) )
  603.     {
  604.         hr = g_pDP->Connect(&dpnAppDesc,        // pdnAppDesc
  605.                             pHostAddress,       // pHostAddr
  606.                             g_pDeviceAddress,   // pDeviceInfo
  607.                             NULL,               // pdnSecurity
  608.                             NULL,               // pdnCredentials
  609.                             NULL, 0,            // pvUserConnectData/Size
  610.                             NULL,               // pvPlayerContext
  611.                             NULL,               // pvAsyncContext
  612.                             NULL,               // pvAsyncHandle
  613.                             DPNCONNECT_SYNC);   // dwFlags
  614.  
  615.         if( FAILED( hr))
  616.             printf("Failed Connecting to Host:  0x%x\n", hr);
  617.     }
  618.     else
  619.     {
  620.         printf("Failed Duplicating Host Address:  0x%x\n", hr);
  621.     }
  622.  
  623.     LeaveCriticalSection(&g_csHostList);
  624.  
  625.     SAFE_RELEASE(pHostAddress);
  626.     return hr;
  627. }
  628.  
  629.  
  630.  
  631.  
  632. //-----------------------------------------------------------------------------
  633. // Name: SendDirectPlayMessage()
  634. // Desc: Sends a DirectPlay message to all players
  635. //-----------------------------------------------------------------------------
  636. HRESULT SendDirectPlayMessage()
  637. {
  638.     HRESULT         hr = S_OK;
  639.     DPN_BUFFER_DESC dpnBuffer;
  640.     WCHAR           wszData[256];
  641.  
  642.     // Get the data from the user
  643.     printf("\nPlease Enter a String.\n");
  644.     wscanf(L"%ls", wszData);
  645.  
  646.     dpnBuffer.pBufferData = (BYTE*) wszData;
  647.     dpnBuffer.dwBufferSize = 2 * (wcslen(wszData) + 1);
  648.  
  649.     if( FAILED( hr = g_pDP->SendTo( DPNID_ALL_PLAYERS_GROUP,  // dpnid
  650.                                     &dpnBuffer,             // pBufferDesc
  651.                                     1,                      // cBufferDesc
  652.                                     0,                      // dwTimeOut
  653.                                     NULL,                   // pvAsyncContext
  654.                                     NULL,                   // pvAsyncHandle
  655.                                     DPNSEND_SYNC |
  656.                                     DPNSEND_NOLOOPBACK ) ) )   // dwFlags
  657.     {
  658.         printf("Failed Sending Data:  0x%x\n", hr);
  659.     }
  660.     return hr;
  661. }
  662.  
  663.  
  664.  
  665.  
  666. //-----------------------------------------------------------------------------
  667. // Name: CleanupDirectPlay()
  668. // Desc: Cleanup DirectPlay
  669. //-----------------------------------------------------------------------------
  670. void CleanupDirectPlay()
  671. {
  672.     HOST_NODE* pHostNode = NULL;
  673.     HOST_NODE* pHostNodetmp = NULL;
  674.  
  675.     // Cleanup DirectPlay
  676.     if( g_pDP)
  677.         g_pDP->Close(0);
  678.  
  679.     // Clean up Host list
  680.     EnterCriticalSection(&g_csHostList);
  681.     
  682.     pHostNode = g_pHostList;
  683.     while( pHostNode != NULL )
  684.     {       
  685.         SAFE_RELEASE(pHostNode->pHostAddress);
  686.         SAFE_DELETE(pHostNode->pAppDesc);
  687.         SAFE_DELETE(pHostNode->pwszSessionName);
  688.  
  689.         pHostNodetmp = pHostNode;
  690.         pHostNode    = pHostNode->pNext;
  691.         SAFE_DELETE(pHostNodetmp);
  692.     }
  693.  
  694.     LeaveCriticalSection(&g_csHostList);
  695.  
  696.     SAFE_RELEASE(g_pDeviceAddress);
  697.     SAFE_RELEASE(g_pHostAddress);
  698.     SAFE_RELEASE(g_pDP);
  699.  
  700.     DeleteCriticalSection(&g_csHostList);
  701. }
  702.     
  703.